home *** CD-ROM | disk | FTP | other *** search
- %From: Donald Arseneau <ASND@TRIUMFCL.BITNET>
- %Subject: Variable indentation puzzle
- %
- %The puzzle in TeXmag V4N1 about making indentation match the length of
- %the line above is interesting because there are (at least) two very different
- %approaches. One is to set every paragraph in a \vbox in order to measure the
- %width of its last line. I hope someone sends in a solution using that method
- %because I chose the method suggested by the question: "(as per what is done
- %with displayed equations)."
- % The width of the line above a displayed equation
- %is given with the parameter \predisplaysize, so it would seem trivial to use
- %a displayed equation to measure the line width. However, there are some
- %details to keep things interesting: The vertical spacing must be the same
- %as for an ordinary paragraph, including the \parskip; Likewise for the
- %penalties; The depths must be preserved, especially if a pagebreak occurs;
- %If the indentation gets too wide something must be done to prevent a bad
- %linebreak. The unboxing method has this last problem too, but there it may
- %be possible to reset the final line to the full textwidth. Here I use
- %ordinary indentation when the line gets too long. The advantage the display
- %method has over reboxing is that there are things that cannot be pulled
- %of a vertical list, so reboxing won't always work.
-
- \newdimen \normalparindent
- \newdimen \longlinelen
- \newdimen \gscratch % used globally
-
- % useful little macro: gives absolute value of a number or a dimension (if in
- % a dimension register). Note that this makes use of TeX's confusing habit of
- % expanding \if's within a number
-
- \def\abs#1{\ifnum#1<0 -\fi#1}
-
- % \usevarindent turns on variable indentation. Use grouping to turn it off.
- % (It would be easy to convert this to a LaTeX environment.)
- % It is necessary to say \usevarindent before ending the paragraph
- % above the first variable indentation.
-
- \def\usevarindent{%
- % don't try indenting to within 2\parindent of the right margin
- \normalparindent=\parindent
- \longlinelen=\hsize \advance\longlinelen-2\normalparindent
- \displaywidowpenalty=\widowpenalty
- \let\par=\varindent}
-
- % \varindent is used to end each paragraph during variable indentation.
-
- \def\varindent{\ifhmode\ifinner\else $$ % test for unrestricted horizontal mode
- \lineskiplimit=-999pt % so we get a baselineskip that we can cancel with:
- \abovedisplayskip=-\baselineskip \abovedisplayshortskip=-\baselineskip
- \belowdisplayskip=0pt \belowdisplayshortskip=0pt
- \halign{##\cr\noalign{\global\gscratch=\prevdepth}% get depth of line above
- \hbox{\vrule width0pt depth \gscratch }\cr}% preserve its depth
- % now get the width of the last line of the paragraph that just ended,
- % If it is too long just use normal indentation:
- \ifdim\abs\predisplaysize>\longlinelen \global\gscratch=\normalparindent
- % otherwise, use the width of the line above (\predisplaysize-2em):
- \else\global\gscratch=\predisplaysize \global\advance\gscratch -2em\fi
- $$\parindent=\gscratch
- \fi\fi \endgraf}% Plain TeX sets \endgraf=\par; use \@@par in LaTeX
-
-